Skip to content

Conversation

Marcondiro
Copy link
Contributor

Description

This PR improves VM tracing in libafl_qemu with Intel PT.

  • Better filter out the VMX root traces during decoding thanks to the new resync API in libipt (bumped to 0.4.0).
  • Extract the Decoder from the linux intel_pt file, since the file/struct was getting too big and the decoder will eventually be compatible with windows.
  • PT tracing is now enabled manually by fuzzers to have more precise control, instead of beeing always on in vm operations.
  • Add KVM dirty tracing option to qemu config and raw string options

Checklist

  • I have run ./scripts/precommit.sh and addressed all comments

@Marcondiro Marcondiro marked this pull request as draft July 28, 2025 12:21
@Marcondiro Marcondiro marked this pull request as ready for review July 28, 2025 13:38
@tokatoka tokatoka requested a review from rmalmain July 29, 2025 12:19
@Marcondiro Marcondiro force-pushed the for_upstream branch 4 times, most recently from 0c42ca4 to 3251229 Compare August 5, 2025 15:17
@Marcondiro Marcondiro force-pushed the for_upstream branch 5 times, most recently from e739390 to 39c2114 Compare August 14, 2025 09:05
@Marcondiro
Copy link
Contributor Author

Hi, is there any chance someone could take a look at this? Thanks :)

.map(|filter| {
let size = filter.end() - filter.start();
format!("filter {:#016x}/{:#016x} ", filter.start(), size)
let size = filter.to - filter.from;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it filter.to - filter.from + 1 (it seems to be an inclusive range)?
i only found little information in the intel manual about this, at section 34.2.5.3 - Filtering by IP.
It could be interesting to add a method len to AddrFilter, and maybe some traits implemented by RangeInclusive that could be relevant.
Screenshot_select-area_20250901180816

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, there is indeed a -1 on the perf side https://elixir.bootlin.com/linux/v6.16.4/source/arch/x86/events/intel/pt.c#L1467
fixing it

let str_filter = filters
.iter()
.filter(|f| f.filter_type == AddrFilterType::FILTER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about AddrFilterType::STOP and AddrFilterType::DISABLED? they seem to be unused.
i saw you create AddrFilterType in libipt. why not use the same names as in the manual (FilterEn and TraceStop)?
by the way, the name of the cfg register in the doc is wrong. it's not IA32_RTIT_ADDRn_CFG, but IA32_RTIT_CTL. or at least i couldn't find this name in the latest version of the intel manual.
Screenshot_select-area_20250901184515

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about AddrFilterType::STOP and AddrFilterType::DISABLED?

They are not supported here at the moment, I add a note to the function docs

why not use the same names as in the manual (FilterEn and TraceStop)?

These were the names already in use in libipt-rs, that are aligned with the ones used by perf

it's not IA32_RTIT_ADDRn_CFG, but IA32_RTIT_CTL

I add the missing _CTL. thanks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not supported here at the moment, I add a note to the function docs

in that case, i'd say it's better to return an error if something different from FILTER is used then.

These were the names already in use in libipt-rs, that are aligned with the ones used by perf

since libipt refers to architectural stuff, i think it makes more sense to keep the naming consistent with the manual, but i guess that's a matter of preference.
however, shouldn't STOP be TRACE_STOP instead according to the perf nomenclature?

Screenshot_select-area_20250902111534

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case, i'd say it's better to return an error if something different from FILTER is used then.

Ok adding it

however, shouldn't STOP be TRACE_STOP instead according to the perf nomenclature?

yes

- Better filter out the VMX root traces during decoding thanks to the new `resync` API in libipt (bumped to 0.4.0).
- Extract the Decoder from the linux intel_pt file, since the file/struct was getting too big and the decoder will eventually be compatible with windows.
- PT tracing is now enabled manually by fuzzers to have more precise control, instead of beeing always on in vm operations.
- Add KVM dirty tracing option to qemu config and raw string options
Instead of hardcoding the addresses (that are compiler dependent), read them from the binary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants